package cn.yunyichina.provider.pay.service;

import cn.yunyichina.provider.framework.dubbo.service.BaseService;
import cn.yunyichina.provider.framework.dubbo.service.ClinicService;
import cn.yunyichina.provider.framework.dubbo.service.MessageService;
import cn.yunyichina.provider.framework.dubbo.service.PayService;
import cn.yunyichina.provider.iface.entity.base.OrderExtVo;
import cn.yunyichina.provider.iface.entity.clinic.ClinicOrder;
import cn.yunyichina.provider.iface.entity.common.Response;
import cn.yunyichina.provider.iface.entity.common.ResponseObject;
import cn.yunyichina.provider.iface.entity.common.TestFlag;
import cn.yunyichina.provider.iface.entity.pay.PaymentJournalVo;
import cn.yunyichina.provider.pay.constant.OrgCode;
import cn.yunyichina.provider.pay.dao.PaymentJournalDao;
import cn.yunyichina.provider.pay.entity.HaiCiRefundResponse;
import cn.yunyichina.provider.pay.entity.PaymentJournal;
import cn.yunyichina.provider.pay.vo.OriginRefundChannelVoRequest;
import cn.yunyichina.utils.commons.DateUtils;
import cn.yunyichina.utils.commons.XmlUtils;
import cn.yunyichina.utils.convert.JsonUtils;
import cn.yunyichina.utils.log.Log;
import cn.yunyichina.utils.log.constant.LogParamType;
import cn.yunyichina.utils.log.constant.LogScene;
import cn.yunyichina.utils.network.HttpsUtil;
import cn.yunyichina.utils.security.MD5Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.openxmlformats.schemas.drawingml.x2006.main.STAdjCoordinate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class RefundServiceImpl {

    static Logger log = LoggerFactory.getLogger(RefundServiceImpl.class);

    @Autowired
    private PaymentJournalDao paymentJournalDao;

    @Autowired
    private UnifiedRefundService unifiedRefundService;

    /**
     * 原渠道退款
     * yyt.pay.refund.channel.origin()
     */
    public Response originRefundChannel(String data) {
//        log.info("原渠道退款, 方法入参data=" + data);
        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,"",
                "原渠道退款, 方法入参data=" + data);
        Response response = new Response();

        OriginRefundChannelVoRequest originRefundChannelVoRequest = JsonUtils.parseObject(data, OriginRefundChannelVoRequest.class);

        Map<String, String> dataMap = new HashMap<>();
        String refundTime = "";
        dataMap.put("order_no", originRefundChannelVoRequest.getOrderNo());
        Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调base模块, 查询订单接口入参request="
                + JSON.toJSONString(dataMap));
        Response ordResponse = BaseService.callUnderlineFromInternal(
                "yyt.base.order.by.order.no.out.get", JsonUtils.toJsonString(dataMap));
        Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调base模块, 查询订单接口返回response="
                + JSON.toJSONString(ordResponse));
        if (!"0".equals(ordResponse.getResultCode())) {
            response.setResultCodeAndMessage("3000", "查询订单失败。");
            return response;
        }
        OrderExtVo order = JsonUtils.parseObject(ordResponse.getResult(), OrderExtVo.class);
        if (StringUtils.isBlank(originRefundChannelVoRequest.getHospitalCode())) {
            originRefundChannelVoRequest.setHospitalCode(order.getOrgCode());
        }

//        PaymentJournal wheres = new PaymentJournal();
//        wheres.setOrderNo(originRefundChannelVoRequest.getOrderNo());
//        wheres.setPayStatus((short) 1);
        HashMap<String, Object> params = new HashMap<>();
        params.put("orderNo", originRefundChannelVoRequest.getOrderNo());
        List<Integer> statuses = new ArrayList<>();
        statuses.add(1);
        statuses.add(4);
        statuses.add(6);
        params.put("statuses", statuses);
        List<PaymentJournal> paymentJournals = paymentJournalDao.selectByOrderNoAndStatuses(params);
        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.RESPONSE,originRefundChannelVoRequest.getOrderNo(),
                "查询支付流水结果paymentJournals=" + JSON.toJSONString(paymentJournals));
        if (paymentJournals.size() == 0) {
            response = new Response("5000", "查询不到对应的订单流水记录!");
            return response;
        }

        PaymentJournal paymentJournal = paymentJournals.get(0);
        if (paymentJournal.getPlatformName().indexOf("海鹚") == -1) {
            Map<String, Object> map = new HashMap<>();
            // 是否已退完全部费用
            boolean isFullRefund = true;

            // PayStatus=7为已退费，说明订单已经退完费，直接返回。
            if (order.getPayStatus().intValue() == 7) {
                String extraParams = order.getExtraParams();
                JSONObject jsonObject = JSON.parseObject(extraParams);
                Map result = new HashMap();
                result.put("payment_deal_id", jsonObject.getString("payment_deal_id"));
                result.put("platform_order_no", order.getOrderNo());
                result.put("refund_yyt_deal_id", jsonObject.getString("refund_yyt_deal_id"));
                response = new Response("3011", "该订单已退过费。", JsonUtils.toJsonString(result));
                return response;
            }

            // 是否需要退费
            boolean isNeedRefund = true;
            // 是否退自费部分
            boolean isRefundPayAmount = false;
            // 是否只退自费部分
            boolean isOnlyRefundPayAmount = false;

            // InsuranceMode为空是自费单
            if (order.getInsuranceMode() == null || order.getInsuranceMode() == 0) {
                // 自费退费
                isRefundPayAmount = true;
                isOnlyRefundPayAmount=true;
            }

            // InsuranceMode=4为医保医院结算，IsFromRefundScheduler为空说明是医院发起的退费，所以只需要退自费部分
            if (order.getInsuranceMode() != null && order.getInsuranceMode().intValue() == 4) {
                // 自费退费
                isRefundPayAmount = true;
                // 只退自费部门
                isOnlyRefundPayAmount = true;

                // 全额医保不需要退费
                if (order.getPayAmount() == null || order.getPayAmount().intValue() == 0) {
                    isNeedRefund = false;
                }
            }

            if (isNeedRefund) {
                if (isRefundPayAmount) {
                    int payAmount = 0;
                    // RefundFlag=2为部分退费
                    if (originRefundChannelVoRequest.getRefundFlag().intValue() == 2) {
                        int refundPayAmount = 0;

                        //判断该笔流水是否已退费,如果已退费提示his
                        if(StringUtils.isNotBlank(originRefundChannelVoRequest.getHisOrderNo())){
                            PaymentJournal exPaymentJournal = new PaymentJournal();
                            exPaymentJournal.setOrderNo(originRefundChannelVoRequest.getOrderNo());
                            exPaymentJournal.setHisOrderNo(originRefundChannelVoRequest.getHisOrderNo());
                            exPaymentJournal.setPayStatus((short) 2);
                            List<PaymentJournal> exRefundPaymentJournals = paymentJournalDao.select(exPaymentJournal);
                            if(exRefundPaymentJournals.size() > 0){
                                PaymentJournal journal = exRefundPaymentJournals.get(0);
                                Map<String ,String> rmap = new HashMap<String , String >();
                                rmap.put("platform_order_no", journal.getOrderNo());
                                rmap.put("refund_yyt_deal_id", journal.getPaymentDealId());
                                rmap.put("payment_deal_id", journal.getPaymentDealId());
                                response.setResultCodeAndMessageAndResult("3011", "该HisNewOrderNo已退费，请传入唯一值" , JsonUtils.toJsonString(rmap));
                                return response;
                            }
                        }

                        PaymentJournal refundWheres = new PaymentJournal();
                        refundWheres.setOrderNo(originRefundChannelVoRequest.getOrderNo());
                        refundWheres.setPayStatus((short) 2);
                        // 查询订单退费流水
                        List<PaymentJournal> refundPaymentJournals = paymentJournalDao.select(refundWheres);
                        if (refundPaymentJournals.size() > 0) {
                            // 计算已退费金额，用于对比正负流水金额，判断是否还可以进行退费。
                            for (PaymentJournal refundPaymentJournal : refundPaymentJournals) {
                                refundPayAmount += refundPaymentJournal.getPayAmount().intValue();
                            }
                        }
//                        log.info("原渠道退款, 已退费金额refundPayAmount=" + refundPayAmount);
                        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.NORMAL,originRefundChannelVoRequest.getOrderNo(),
                                "原渠道退款, 已退费金额refundPayAmount=" + refundPayAmount);
                        // 判断此次退费后，是否已经全部退完。
                        if (paymentJournal.getPayAmount() > (refundPayAmount
                                + originRefundChannelVoRequest.getRefundAmount().intValue())) {
                            isFullRefund = false;
                        }

                        if (paymentJournal.getPayAmount() >= (refundPayAmount
                                + originRefundChannelVoRequest.getRefundAmount().intValue())) {
                            payAmount = originRefundChannelVoRequest.getRefundAmount().intValue();
                        } else {
                            response.setResultCodeAndMessage("3000", "退费金额大于支付金额。");
                            return response;
                        }
                    } else {
                        if (isOnlyRefundPayAmount) {
                            payAmount = paymentJournal.getPayAmount();
                        } else {
                            payAmount = paymentJournal.getTotalAmount();
                        }
                    }
                    map.put("refund_fee", String.valueOf(payAmount));
                } else {
                    int refundFee = 0;
                    // RefundFlag=2为部分退费（目前医保退费没有部分退费部分，只是代码暂时保留。）
                    if (originRefundChannelVoRequest.getRefundFlag().intValue() == 2) {
                        int refundPayAmount = 0;
                        PaymentJournal refundWheres = new PaymentJournal();
                        refundWheres.setOrderNo(originRefundChannelVoRequest.getOrderNo());
                        refundWheres.setPayStatus((short) 2);
                        // 查询订单退费流水
                        List<PaymentJournal> refundPaymentJournals = paymentJournalDao.select(refundWheres);
//                        log.info("原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo()
//                                + ", 查询退费流水结果refundPaymentJournals=" + JSON.toJSONString(refundPaymentJournals));
                        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.RESPONSE,originRefundChannelVoRequest.getOrderNo(),
                                "查询退费流水结果refundPaymentJournals==" + JSON.toJSONString(refundPaymentJournals));
                        if (refundPaymentJournals.size() > 0) {
                            // 计算已退费金额，用于对比正负流水金额，判断是否还可以进行退费。
                            for (PaymentJournal refundPaymentJournal : refundPaymentJournals) {
                                refundPayAmount += refundPaymentJournal.getInsuranceAmount().intValue();
                            }
                        }
                        Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"原渠道退款, 已退费金额refundPayAmount=" + refundPayAmount);
                        // 判断此次退费后，是否已经全部退完。
                        if (paymentJournal.getInsuranceAmount() > (refundPayAmount
                                + originRefundChannelVoRequest.getRefundAmount().intValue())) {
                            isFullRefund = false;
                        }
                        if (paymentJournal.getInsuranceAmount() >= (refundPayAmount
                                + originRefundChannelVoRequest.getRefundAmount().intValue())) {
                            refundFee = originRefundChannelVoRequest.getRefundAmount().intValue();
                        } else {
                            response.setResultCodeAndMessage("3000", "退费金额大于支付金额。");
                            return response;
                        }
                    } else {
                        refundFee = paymentJournal.getTotalAmount().intValue();
                    }
                    map.put("refund_fee", String.valueOf(refundFee));

                    JSONObject extraParamsMap = JsonUtils.parseObject(order.getExtraParams());
                    map.put("cancel_serial_no", extraParamsMap.getString("cancel_serial_no"));
                    map.put("cancel_bill_no", extraParamsMap.getString("cancel_bill_no"));
                    map.put("hosp_out_refund_no", extraParamsMap.getString("ss_bill_no"));
                    map.put("hosp_out_trade_no", extraParamsMap.getString("ss_fee_no"));
                }
            } else {
                // 全额医保添加反向流水
                addPaymentJournal(order, true);

                ClinicOrder co = new ClinicOrder();
                co.setOrderNo(paymentJournal.getOrderNo());
                co.setOrgId(paymentJournal.getOrgId());
                co.setPayStatus(7);
                co.setOrderStatus(7);
                ClinicService.getClinicClient().updateClinicOrder(co);
                response.setResultCodeAndMessage("3011", "全额医保退费不调用海鹚接口。");
                response.setResult("{\"refund_yyt_deal_id\":\"" + paymentJournal.getOrderNo()
                        + "\",\"payment_deal_id\":\"" + paymentJournal.getOrderNo() + "\"}");
                return response;
            }
            // 云医宝调公共支付退费接口
            Short payMode = paymentJournal.getPayMode();
            if (payMode != null) {
                if (payMode.intValue() == 16) {
                    map.put("pay_code", "WECHATMEDICAL");
                    map.put("order_type", order.getOrderType().intValue() == 1 ? "REGPAY" : "DIAGPAY");
                    map.put("is_insurance", order.getIsInsurance().intValue() == 1 ? "YEP" : "NOPE");
                } else if (payMode == 2 || (payMode > 20 && payMode < 30) || payMode == 212) {
                    map.put("pay_code", "ALIPAY");
                } else if (payMode == 1 || (payMode > 10 && payMode < 20)) {
                    map.put("pay_code", "WECHAT");
                } else if (payMode == 8) {
                    map.put("pay_code", "PACITY");
                } else if (payMode == 31) {
                    map.put("app_code", order.getPlatformOrgAppCode());
                    map.put("org_code", order.getOrgCode());
                    map.put("pay_code", "HYMEDUNION");
                } else {
                    throw new RuntimeException("Refund channel unsupported");
                }
            }
            map.put("app_id", paymentJournal.getPayAppId());
            map.put("order_no", paymentJournal.getOrderNo());
            map.put("hospital_code", order.getOrgCode());

            //修改逻辑如果支付方式是：微信自费+线下医保->推出退费的总金额采用自费的总金额
            if (map.containsKey("pay_code") && "WECHAT".equals(map.get("pay_code")) && order.getInsuranceMode() != null && order.getInsuranceMode().intValue() == 4) {
                map.put("total_fee", String.valueOf(paymentJournal.getPayAmount()));
            }else if (map.containsKey("pay_code") && "WECHAT".equals(map.get("pay_code")) &&
                    (order.getInsuranceMode() == null || order.getInsuranceMode().intValue() == 0)) {
                map.put("total_fee", String.valueOf(paymentJournal.getPayAmount()));
            }
            else {
                map.put("total_fee", String.valueOf(paymentJournal.getTotalAmount()));
            }

            map.put("pay_order_no", paymentJournal.getPaymentDealId());
//            log.info("原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调用pay-lite模块, 退费接口入参request=" + JsonUtils.toJsonString(map));
            Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,originRefundChannelVoRequest.getOrderNo(),
                    "调用pay-lite模块, 退费接口入参request=" +JsonUtils.toJsonString(map));

            ResponseObject responseObject = unifiedRefundService.refundUnified(JsonUtils.toJsonString(map));
//            log.info("原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调用pay-lite模块, 退费接口返回response="
//                    + JSON.toJSONString(responseObject));
            Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.RESPONSE,originRefundChannelVoRequest.getOrderNo(),
                    "调用pay-lite模块, 退费接口返回response=" + JSON.toJSONString(responseObject));
            if ("0".equals(responseObject.getResultCode())) {
                Map result = JsonUtils.parseObject(responseObject.getResultObject(), Map.class);
//                log.info("原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 退费接口返回result="
//                        + JSON.toJSONString(result));
                if (result != null) {
//                    log.info("原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", pay_transaction_id="
//                            + result.get("pay_transaction_id") + ", platform_serial_number="
//                            + result.get("platform_serial_number"));
                    result.put("payment_deal_id", result.get("pay_transaction_id"));
                    result.put("refund_yyt_deal_id", result.get("platform_serial_number"));

                    //存豪那边需求：如果订单是深中的，那么退费的订单号，要和原来正交易单号不一样
                    if (OrgCode.SZ_SZSZYY.getValue().equals(order.getOrgCode())) {
                        result.put("platform_order_no", result.get("platform_serial_number"));
                    }

                    Map<String, String> tmpMap = new HashMap<String, String>();
                    tmpMap.put("order_no", originRefundChannelVoRequest.getOrderNo());
                    Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调用base模块, 查询订单入参tmpMap="
                            + JSON.toJSONString(tmpMap));
                    Response tmpRes = BaseService.callUnderlineFromInternal("", "yyt.base.order.by.order.no.out.get",
                            JsonUtils.toJsonString(tmpMap));
                    Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"原渠道退款, 订单号" + originRefundChannelVoRequest.getOrderNo() + ", 调用base模块, 查询订单返回tmpRes="
                            + JSON.toJSONString(tmpRes));
                    if (!"0".equals(tmpRes.getResultCode())) {
                        response.setResultCodeAndMessage("3000", "查询订单失败。");
                        return response;
                    }
                    order = JsonUtils.parseObject(tmpRes.getResult(), OrderExtVo.class);
                    Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), HashMap.class);
                    if (extraParamsMap == null) {
                        extraParamsMap = new HashMap<String, String>();
                    }
                    extraParamsMap.put("payment_deal_id", result.get("payment_deal_id") != null
                            ? String.valueOf(result.get("payment_deal_id")) : "");
                    extraParamsMap.put("refund_yyt_deal_id", result.get("refund_yyt_deal_id") != null
                            ? String.valueOf(result.get("refund_yyt_deal_id")) : "");
                    order.setExtraParams(JsonUtils.toJsonString(extraParamsMap));

                    Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,originRefundChannelVoRequest.getOrderNo(),
                            "原渠道退款,调用base模块, 更新订单信息入参order=" + JSONObject.toJSONString(order));

                    refundTime = DateUtils.dateToString(new Date());
                    order.setRefundTime(refundTime);
                    BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));

                    //如果存在hisNewOrdNum查出退费流水并更新
                    if(StringUtils.isNotBlank(originRefundChannelVoRequest.getHisOrderNo())){
                        PaymentJournal payJournal = new PaymentJournal();
                        payJournal.setOrderNo(originRefundChannelVoRequest.getOrderNo());
                        payJournal.setPaymentDealId((String) result.get("payment_deal_id"));
                        payJournal.setPayStatus((short) 2);
                        List<PaymentJournal> payJournals = paymentJournalDao.select(payJournal);
                        if(payJournals.size() > 0){
                            PaymentJournal journal = payJournals.get(0);
                            journal.setHisOrderNo(originRefundChannelVoRequest.getHisOrderNo());
                            paymentJournalDao.update(journal);
                        }else{
                            Log.i(LogScene.PAY_ORIGIN_REFUND,originRefundChannelVoRequest.getOrderNo(),"如果存在hisNewOrdNum查出退费流水并更新流程 查无结果,条件：" + JsonUtils.toJsonString(payJournal));
                        }
                    }else{
//                        log.info("更新hisOrderNo失败 接口传入参数不存在！");
                        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.NORMAL,originRefundChannelVoRequest.getOrderNo(),
                                "更新hisOrderNo失败 接口传入参数不存在！");
                    }
                }
                response = new Response("0", "退款成功", JsonUtils.toJsonString(result));
                ClinicOrder co = new ClinicOrder();
                co.setOrderNo(paymentJournal.getOrderNo());
                co.setOrgId(paymentJournal.getOrgId());
                if (originRefundChannelVoRequest.getIsFromRefundScheduler() != null
                        && originRefundChannelVoRequest.getIsFromRefundScheduler().intValue() == 1) {
                    // 定时任务退费流程进来的，不确定是否退完自费和医保两部分，所以都改成部分退费成功，在退费流程中判断是否全部退完
                    co.setPayStatus(8);
                    co.setOrderStatus(order.getOrderStatus().intValue());
                } else {
                    if (isFullRefund) {
                        co.setPayStatus(7);
                        co.setOrderStatus(7);
                    } else {
                        co.setPayStatus(8);
                        co.setOrderStatus(order.getOrderStatus().intValue());
                    }
                }
                ClinicService.getClinicClient().updateClinicOrder(co);
                // 消息推送
                try {
                    Map<String, Object> extraParams = JsonUtils.parseObject(order.getExtraParams(), Map.class);
                    String messageContent = "";
                    String method = "yyt.message.msg.template.send";
                    String platformType = "2";
                    if ("1".equals(String.valueOf(Integer.valueOf(order.getPayMode()) / 10 % 10))) {
                        platformType = "1";
                    } else if ("2".equals(String.valueOf(Integer.valueOf(order.getPayMode()) / 10 % 10))) {
                        platformType = "2";
                    }
                    if (order.getOrderType() == 1) {//挂号
                        String scheduleTime = order.getScheduleTime();
                        if (scheduleTime != null && scheduleTime.length() > 10) {
                            scheduleTime = scheduleTime.substring(0, 10);
                            scheduleTime += " " + extraParams.get("begin_time") + "-" + extraParams.get("end_time");
                        }
                        messageContent = "{\"user_type\":\"2\",\"order_no\":\"" + order.getOrderNo()
                                + "\",\"platform_type\":\"" + platformType + "\",\"org_app_code\":\"" + order.getPlatformOrgAppCode() + "\",\"org_code\":\"" + order.getOrgCode() + "\",\"to_user\":\""
                                + order.getOpenId()
                                + "\",\"template_code\":\"21003\",\"msg_content\":\"{\\\"first\\\": \\\"您好，您的挂号已取消成功。\\\"," +
                                "\\\"keyword1\\\": \\\""
                                + order.getUserName()
                                + "\\\",\\\"keyword2\\\": \\\""
                                + scheduleTime
                                + "\\\",\\\"keyword3\\\": \\\""
                                + order.getDeptName()
                                + "\\\",\\\"keyword4\\\": \\\""
                                + order.getDoctorName()
                                + "\\\",\\\"remark\\\": \\\"感谢您的使用:"
                                + "\\\"}\"}";
                    } else if (order.getOrderType() == 3) {//门诊
                        messageContent = "{\"user_type\":\"2\",\"order_no\":\"" + order.getOrderNo()
                                + "\",\"platform_type\":\"" + platformType + "\",\"org_app_code\":\"" + order.getPlatformOrgAppCode() + "\",\"org_code\":\"" + order.getOrgCode() + "\",\"to_user\":\""
                                + order.getOpenId()
                                + "\",\"template_code\":\"22004\",\"msg_content\":\"{\\\"first\\\": \\\"退款成功，款项将自动退回付款账户，请留意账户变化。\\\"," +
                                "\\\"keyword1\\\": \\\""
                                + order.getOrderNo()
                                + "\\\",\\\"keyword2\\\": \\\""
                                + "已退费"
                                + "\\\",\\\"keyword3\\\": \\\""
                                + refundTime
                                + "\\\",\\\"keyword4\\\": \\\""
                                + "48小时内，具体时间以银行通知为准。"
                                + "\\\",\\\"remark\\\": \\\"如有任何疑问，请致电医院客服电话咨询。"
                                + "\\\"}\"}";
                    }
//                    log.info("originRefundChannel原渠道退费接口, 订单号" + order.getOrderNo() + ", 调用message模块, 消息推送接口入参request="
//                            + messageContent);
                    Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,order.getOrderNo(),
                            "调用message模块, 消息推送接口入参request=" + messageContent);
                    Response messageResponse = MessageService.callHumpFromInternal(method, messageContent);
//                    log.info("originRefundChannel原渠道退费接口, 调用message模块, 消息推送接口返回response="
//                            + JSON.toJSONString(messageResponse));
                    Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,order.getOrderNo(),
                            "调用message模块, 消息推送接口返回response=" + JSON.toJSONString(messageResponse));
                } catch (Exception e) {
//                    log.error("originRefundChannel原渠道退费接口,原渠道退费接口消息推送失败:", e);
                    Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.EXCEPTION,order.getOrderNo(),
                            "原渠道退费接口,原渠道退费接口消息推送失败");
                }
                return response;
            } else {
                // 退款失败
                response.setResultCodeAndMessage(responseObject.getResultCode(), responseObject.getResultMessage());
                return response;
            }

        } else {
            // 海鹚退费添加流水
            addPaymentJournal(order, false);

            // 全额医保不调用海鹚退费接口
            if (paymentJournal.getPayAmount() != null && 0 != paymentJournal.getPayAmount().intValue()) {
                // TODO:先处理海鹚的
                if (paymentJournal.getPlatformName().indexOf("海鹚") >= 0) {// 云医宝的不调用海鹚
                    if (order.getPayStatus().intValue() == 7) {
                        String extraParams = order.getExtraParams();
                        JSONObject jsonObject = JSON.parseObject(extraParams);
                        Map result = new HashMap();
                        result.put("payment_deal_id", jsonObject.getString("payment_deal_id"));
                        result.put("platform_order_no", order.getOrderNo());
                        result.put("refund_yyt_deal_id", jsonObject.getString("refund_yyt_deal_id"));
                        response = new Response("3011", "该订单已退过费。", JsonUtils.toJsonString(result));
                        return response;
                    }

                    response = refundHaiCi(originRefundChannelVoRequest, paymentJournal, order);
//                    log.info("退款返回->" + JSON.toJSONString(response));
                    Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.RESPONSE,originRefundChannelVoRequest.getOrderNo(),
                            "refundHaiCi, 退款返回->" + JSON.toJSONString(response));
                }
            } else {
                ClinicOrder co = new ClinicOrder();
                co.setOrderNo(paymentJournal.getOrderNo());
                co.setOrgId(paymentJournal.getOrgId());
                if (originRefundChannelVoRequest.getIsFromRefundScheduler() != null
                        && originRefundChannelVoRequest.getIsFromRefundScheduler().intValue() == 1) {
                    // 定时任务退费流程进来的，不确定是否退完自费和医保两部分，所以都改成部分退费成功，在退费流程中判断是否全部退完
                    co.setPayStatus(8);
                    co.setOrderStatus(order.getOrderStatus().intValue());
                } else {
                    co.setPayStatus(7);
                    co.setOrderStatus(7);
                }
                ClinicService.getClinicClient().updateClinicOrder(co);
                response.setResultCodeAndMessage("3010", "全额医保退费不调用海鹚接口。");
                response.setResult("{\"refund_yyt_deal_id\":\"" + paymentJournal.getOrderNo() + "\"}");

            }
        }

        return response;
    }

    private Response refundHaiCi(OriginRefundChannelVoRequest originRefundChannelVoRequest,
                                 PaymentJournal paymentJournal, OrderExtVo order) {
        Response response = new Response("5000", "退款失败");
        String partnerId = "";
        if ("bjdxszyy".equals(originRefundChannelVoRequest.getHospitalCode())) {
            partnerId = "BJDXSZYY";
        } else if ("szsdsrmyy".equals(originRefundChannelVoRequest.getHospitalCode())) {
            partnerId = "SZSDSRMYY";
        } else if ("ftqrmyy".equals(originRefundChannelVoRequest.getHospitalCode())) {
            partnerId = "FTQRMYY";
        } else {
            response = new Response("5000", "医院编码转换失败");
            return response;
        }

        String url = "";
        if ("true".equals(TestFlag.TEST_FLAG)) {
            url = "http://uapi.gzhc365.com/openapi/HttpServices";
        } else {
            url = "http://mp.gzhc365.com/openapi/HttpServices";
        }
        String dateTime = DateUtils.dateToString(new Date());
        String key = "51C3B977EE8C1ADDA09ECE608EF726F8";

        StringBuilder sb = new StringBuilder();
        sb.append("<request>");
        sb.append("<serviceCode>PartRefundNotice</serviceCode>");
        sb.append("<partnerId>" + partnerId + "</partnerId>");
        sb.append("<timeStamp>" + dateTime + "</timeStamp>");
        sb.append("<password>" + key + "</password>");
        sb.append("<batchNo>" + originRefundChannelVoRequest.getHisOrderNo() + "</batchNo>");
        sb.append("<SerialNumber>" + paymentJournal.getPaymentDealId() + "</SerialNumber>");
        sb.append("<refundAmout>" + paymentJournal.getPayAmount() + "</refundAmout>");
        sb.append("<refundDesc>" + originRefundChannelVoRequest.getRefundReason() + "</refundDesc>");
        sb.append("<CheckOutNo></CheckOutNo>");
        sb.append("<personalFirst></personalFirst>");
        sb.append("<personalSecond></personalSecond>");
        sb.append("<personalThird></personalThird>");
        sb.append("<personalForth></personalForth>");
        sb.append("</request>");
//        log.info("海鷀退款请求->" + url + "," + sb.toString());
        Log.i(LogScene.PAY_ORIGIN_REFUND,"refundHaiCi", LogParamType.REQUEST,originRefundChannelVoRequest.getOrderNo(),
                "海鷀退款请求->"  + url + "," + sb.toString());
        String result = HttpsUtil.doPost(url, sb.toString());
//        log.info("海鷀退款返回->" + result);
        Log.i(LogScene.PAY_ORIGIN_REFUND,"refundHaiCi", LogParamType.REQUEST,originRefundChannelVoRequest.getOrderNo(),
                "海鷀退款返回->"  + result);
        result = result.replace("<response>", "").replace("</response>", "");
        HaiCiRefundResponse refundResponse = XmlUtils.xmlToObject(result, HaiCiRefundResponse.class);
        if ("0".equals(refundResponse.getResultCode())) {
            String jsonResult = "{\"payment_deal_id\":\"" + refundResponse.getRefundSerialNumber()
                    + "\",\"refund_yyt_deal_id\":\"" + paymentJournal.getOrderNo() + "\"}";
            response = new Response("0", "海鹚退款成功", jsonResult);

            Map<String, String> extraParamsMap = JsonUtils.parseObject(order.getExtraParams(), HashMap.class);
            if (extraParamsMap == null) {
                extraParamsMap = new HashMap<String, String>();
            }
            extraParamsMap.put("payment_deal_id", refundResponse.getRefundSerialNumber() != null
                    ? String.valueOf(refundResponse.getRefundSerialNumber()) : "");
            extraParamsMap.put("refund_yyt_deal_id",
                    paymentJournal.getOrderNo() != null ? String.valueOf(paymentJournal.getOrderNo()) : "");
            order.setExtraParams(JsonUtils.toJsonString(extraParamsMap));

            log.info("refundHaiCi, order=" + JSONObject.toJSONString(order));
            BaseService.callUnderlineFromInternal("yyt.base.order.update", JsonUtils.toJsonString(order));

            ClinicOrder co = new ClinicOrder();
            co.setOrderNo(paymentJournal.getOrderNo());
            co.setOrgId(paymentJournal.getOrgId());
            if (originRefundChannelVoRequest.getIsFromRefundScheduler() != null
                    && originRefundChannelVoRequest.getIsFromRefundScheduler().intValue() == 1) {
                // 定时任务退费流程进来的，不确定是否退完自费和医保两部分，所以都改成部分退费成功，在退费流程中判断是否全部退完
                co.setPayStatus(8);
                co.setOrderStatus(order.getOrderStatus().intValue());
            } else {
                co.setPayStatus(7);
                co.setOrderStatus(7);
            }
            ClinicService.getClinicClient().updateClinicOrder(co);
        } else {
            response = new Response("5000", refundResponse.getResultDesc());
        }
        return response;
    }

    private void addPaymentJournal(OrderExtVo order, boolean isInsurance) {
        PaymentJournalVo tmp = new PaymentJournalVo();
        tmp.setOrderNo(order.getOrderNo());
        tmp.setPayStatus((short) 2);
//        log.info("addPaymentJournal, paymentJournal=" + JSON.toJSONString(tmp));
        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,order.getOrderNo(),
                "addPaymentJournal,paymentJournal="  + JSON.toJSONString(tmp));
        Response findPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.find",
                JsonUtils.toJsonString(tmp));
//        log.info("addPaymentJournal, findPaymentJournalResponse=" + JSON.toJSONString(findPaymentJournalResponse));
        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,order.getOrderNo(),
                "addPaymentJournal,findPaymentJournalResponse="  + JSON.toJSONString(findPaymentJournalResponse));
        if ("0".equals(findPaymentJournalResponse.getResultCode())) {
            List<PaymentJournalVo> list = JsonUtils.parseArray(findPaymentJournalResponse.getResult(), PaymentJournalVo.class);
            int totalAmount = 0;
            for (PaymentJournalVo paymentJournalVo : list) {
                totalAmount += paymentJournalVo.getTotalAmount().intValue();
            }
            if (order.getTotalAmount().intValue() <= totalAmount) {
//                log.info("addPaymentJournal, 退费流水已存在，不再添加。");
                Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.NORMAL,order.getOrderNo(),
                        "addPaymentJournal, 退费流水已存在，不再添加。");
                return;
            }
        }

        PaymentJournalVo paymentJournal = new PaymentJournalVo();
        paymentJournal.setOrgId(order.getOrgId());
        paymentJournal.setOrgName(order.getOrgName());
        paymentJournal.setOrgCode(order.getOrgCode());
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setOrderNo(order.getOrderNo());
        paymentJournal.setOutOrderNo(order.getOutOrderNo());
        paymentJournal.setPaymentDealId(order.getPaymentDealId());
        if (isInsurance) {
            paymentJournal.setMedicareAmount(order.getMedicareAmount());
            paymentJournal.setAccountAmount(order.getAccountAmount());
            paymentJournal.setInsuranceAmount(order.getInsuranceAmount());
            paymentJournal.setTotalAmount(order.getInsuranceAmount());
            paymentJournal.setPayAmount(0);
        } else {
            // 退自费部分时，海鹚非全额医保，医保部分医院已退，需要把自费和医保金额一起入流水。
            paymentJournal.setMedicareAmount(order.getMedicareAmount());
            paymentJournal.setAccountAmount(order.getAccountAmount());
            paymentJournal.setInsuranceAmount(order.getInsuranceAmount());
            paymentJournal.setPayAmount(order.getPayAmount());
            paymentJournal.setTotalAmount(order.getTotalAmount());
        }

        paymentJournal.setPlatformId(order.getPlatformId());
        paymentJournal.setPlatformCode(order.getPlatformCode());
        paymentJournal.setPlatformName(order.getPlatformName());
        paymentJournal.setPlatformOrgAppName(order.getPlatformOrgAppName());
        paymentJournal.setPlatformOrgAppCode(order.getPlatformOrgAppCode());
        paymentJournal.setPayAppId(order.getPayAppId());
        paymentJournal.setDealAccount("");
        paymentJournal.setAccountName("");
        paymentJournal.setPayStatus((short) 2);
        paymentJournal.setHisOrderNo(order.getHisOrderNo());
        paymentJournal.setOrderType(order.getOrderType());
        paymentJournal.setCheckStatus((short) 0);
        paymentJournal.setPayTime(DateUtils.dateToString(new Date()));

        if (order.getPayMode().intValue() == 99) {
            paymentJournal.setPayMode((short) 23);
        } else if (order.getPayMode().intValue() == 99) {
            paymentJournal.setPayMode((short) 13);
        } else {
            paymentJournal.setPayMode((short) order.getPayMode().intValue());
        }

        paymentJournal.setPlatformOrgAppCode(order.getPlatformOrgAppCode());
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setSettlementStatus((short) 0);
        if (order.getInsuranceMode() != null) {
            paymentJournal.setInsuranceMode((short) order.getInsuranceMode().intValue());
        }
        paymentJournal.setBranchId(order.getBranchId());
        paymentJournal.setBranchName(order.getBranchName());
        paymentJournal.setBranchCode(order.getBranchCode());

        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.REQUEST,order.getOrderNo(),
                "新增支付流水请求参数->"  + JSON.toJSONString(paymentJournal));
        Response addPaymentJournalResponse = PayService.callUnderlineFromInternal("yyt.pay.payment.journal.add",
                JsonUtils.toJsonString(paymentJournal));
        Log.i(LogScene.PAY_ORIGIN_REFUND,"yyt.pay.refund.channel.origin", LogParamType.RESPONSE,order.getOrderNo(),
                "新增支付流水返回参数->"  + JSON.toJSONString(addPaymentJournalResponse));
    }

    public static void main(String[] args) {
//        String result="<response><resultCode>0</resultCode><resultDesc>交易成功</resultDesc><refundOrder>201609260049081120</refundOrder><refundSerialNumber>2016092621001004760284227664</refundSerialNumber><refundAmout>14</refundAmout></response>".replace("<response>", "").replace("</response>","");
//        HaiCiRefundResponse response=XmlUtils.xmlToObject(result, HaiCiRefundResponse.class);
//        System.out.print(response.getRefundAmout());

        testNoityHaici();
    }


    public static void testNoityHaici() {

        String url = "http://ump.gzhc365.com/openapi/HttpServices";
        String dateTime = DateUtils.dateToString(new Date());
        //String key="51C3B977EE8C1ADDA09ECE608EF726F8";
        String key = "51C3B977EE8C1ADDA09ECE608EF726F8";
        System.out.println("密钥=" + key);
        String str = dateTime + key;
        System.out.println("待加密=" + str);
        String password = MD5Util.string2MD5(str).toUpperCase();
        System.out.println("加密后=" + password);

        StringBuffer sb = new StringBuffer();
        sb.append("<request>");
        sb.append("<serviceCode>").append("OrderConfirmAllMed").append("</serviceCode>");
        sb.append("<partnerId>").append("BJDXSZYY").append("</partnerId>");
        sb.append("<timeStamp>").append(dateTime).append("</timeStamp>");
        sb.append("<password>").append(key).append("</password>");
        sb.append("<hospital_code>").append("BJDXSZYY").append("</hospital_code>");
        sb.append("<branch_code>").append("").append("</branch_code>");
        sb.append("<yyt_order_no>").append("Y52016110512334987").append("</yyt_order_no>");
        sb.append("<pay_status>").append("1").append("</pay_status>");
        sb.append("</request>");
        System.out.println("请求地址=" + url);
        System.out.println("请求数据:" + sb.toString());
        String result = HttpsUtil.doPost(url, sb.toString());
        System.out.println("结果返回:" + result);
    }
}
